#ifndef _INC_DLIST_T_H_
#define _INC_DLIST_T_H_

#include "Container_t.h"
#include "DlistElem_t.h"

template<class T>
class Dlist_t
	: public Container_t<T>
{
public:
	/**
	* Ctor
	*/
	Dlist_t();

	/**
	* Dtor
	*/
	virtual ~Dlist_t();

	/**
	* Copy Ctor
	*/
	Dlist_t(const Dlist_t& other);

	/**
	* Assignment operator
	*/
	Dlist_t& operator=(const Dlist_t& other);

	/**
	* Returns next elem in list
	*/
	T* next();

	/**
	* Returns previous elem in list
	*/
	T* prev();

	/**
	* Resets inner list iterator
	*/
	void reset();

protected:
	/**
	* Inserts elem after given index in container
	* Precondition: -1 <= index <= count() - 1
	*/
	void doAppend(T* const elem, int index);

	/**
	* Removes elem with given value from container
	*/
	void doRemove(const T& value);

	/**
	* Removes all elements from container
	*/
	void doRemoveAll();

	/**
	* Removes and deletes all elements from container
	*/
	void doRemoveAndDeleteAll();

	/**
	* Returns container iterator
	* Releasing iterator is up to caller
	*/
	Iterator_t<T>* iterator() const;

private:
	template<class Ty>
	friend class DlistIterator_t; // Iterator declaration

	/**
	* Returns pointer to list elem with given value, returns NULL if not found
	*/
	DlistElem_t<T>* lookup(const T& value) const;

	/**
	* Returns pointer to list elem in given index, returns NULL if not found
	*/
	DlistElem_t<T>* lookupIndex(size_t index) const;

	/**
	* Initializes head, tail and curr
	*/
	void initialize();

	DlistElem_t<T>* m_head; // Head list elem
	DlistElem_t<T>* m_curr; // Current list elem
	DlistElem_t<T>* m_tail; // Tail list elem
};

#include "Dlist_t.hpp"

#endif // _INC_DLIST_T_H_